#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <libgen.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <sys/resource.h>
#include "sqlite3.h"
#include"logger.h"
#include"server_connect.h"
#include"server_sqlite.h"

#define         MAX_EVENTS              512

void print_usage(char *progname);//帮助信息
void signal_stop(int signum);//信号处理


static  int     g_stop=0;//标识符

int main(int argc,char* argv[])
{
        int                     listen_fd,client_fd;
        int                     listen_port=0;
        int                     daemon_run=0;
        char                    *progname=NULL;
        struct sockaddr_in      cli_addr;
        socklen_t               len = 20;
        int                     opt;
        int                     rv=-1;
        int                     sock_fd;
        char                    *listen_ip;
        int                     a,i,j;
        int                     found;
        int                     log_fd;
        char                    buf[1024];
        int                     epollfd;
        int                     events;
        struct epoll_event      event;
        struct epoll_event      event_array[MAX_EVENTS];//同时处理多少个客户端
        int                     ret;
        sqlite3                 *db;
        char                    *zErrMsg;

        /*命令行参数*/
        struct option           opts[] = {
        {"daemon",no_argument,NULL,'d'},
        {"port",required_argument,NULL,'p'},
        {"help",no_argument,NULL,'h'},
        {NULL,0,NULL,0}
        };
        //progname=basename(argv[0]);

        while((opt=getopt_long(argc,argv,"dp:h",opts,NULL))!=-1){
                switch(opt){
                        case'd':
                                daemon_run=1;
                                break;
                        case'p':
                                listen_port=atoi(optarg);
                                break;
                        case'h':
                                print_usage(argv[0]);
                                return 0;
                        default:
                                break;
                }
        }

        if( !listen_port){
                print_usage(argv[0]);
                return -1 ;
        }

        /*后台运行*/
        if(daemon_run){
                /*设置守护进程*/
                 if ((daemon(1, 1)) < 0)
                {
                    printf("Deamon failure : %s\n", strerror(errno));
                    return 0;
                }
                printf("Program %s is running at the background now\n",argv[0]);
        }

        /*socket*/
        if ((listen_fd=connect_server(NULL,listen_port))<0){
                printf("listen failure:%s",strerror(errno));
                return -2;
        }
        printf("server start to listen listen_port %d\n",listen_port);

        /*epoll创建内核事件表*/
        if ((epollfd=epoll_create(MAX_EVENTS))<0){
                printf("epoll create failure:%s\n",strerror(errno));
                return 0;
        }
        printf("epoll create successful\n");
        event.events=EPOLLIN;
        event.data.fd=listen_fd;
        /*加入监听事件*/
        if(epoll_ctl(epollfd,EPOLL_CTL_ADD,listen_fd,&event)<0){
                printf("epoll add listen_fd failure:%s\n",strerror(errno));
                return 0;
        }
        printf("epoll add listen_fd successful\n");

        /*安装信号*/
        signal(SIGTERM,signal_stop);
        printf("signal add successful\n");

        /*打开数据库并创建数据表，失败则删除库*/
        sqlite_open_create(db);

        while(!g_stop){

                /*等待事件发生*/
                events=epoll_wait(epollfd,event_array,MAX_EVENTS,-1);
                if(events<0){
                        printf("epoll failure:%s\n",strerror(errno));
                        break;
                }
                else if(events == 0){
                        printf("epoll get timeout\n");
                        continue;
                }
                for(i=0;i<events;i++){
                        if ((event_array[i].events&EPOLLERR)||(event_array[i].events &EPOLLHUP)){
                                printf("epoll_wait get error on fd[%d]:%s\n",event_array[i].data.fd,strerror(errno));
                                epoll_ctl(epollfd,EPOLL_CTL_DEL,event_array[i].data.fd,NULL);
                                close(event_array[i].data.fd);
                        }

                        if(event_array[i].data.fd==listen_fd){
                                client_fd=accept(listen_fd,(struct sockaddr*) & cli_addr, &len);
                                if (client_fd < 0){
                                         printf("Accept the request from client failure:%s\n", strerror(errno));
                                         continue;
                                }
                                event.data.fd = client_fd;
                                event.events = EPOLLIN;
                                if (epoll_ctl(epollfd, EPOLL_CTL_ADD, client_fd, &event) < 0){
                                        printf("epoll add client socket failure:%s\n", strerror(errno));
                                         close(client_fd);
                                         continue;
                                 }
                        }
                        else{
                                /*读取客户端发送的数据*/
                                 memset(buf, 0, sizeof(buf));
                                 a = read(client_fd, buf, sizeof(buf));
                                if (a < 0){
                                        printf("Read information from client failure:%s\n", strerror(errno));
                                        close(client_fd);
                                          exit(0);
                                 }

                                else if (a == 0){
                                    printf("The connection with client has broken!\n");
                                    close(client_fd);
                                    exit(0);
                                }
                                else{
                                        sqlite_create(db);
                                        sqlite_insert(db,buf);
                                        printf("Database inserted successfully!\n");
                                 }

                         }
                }
        }
    close(epollfd);
    close(listen_fd);
    sqlite3_close(db);
    return 0;
}

/*当选项输入错误时，显示此帮助函数*/
void   print_usage(char *progname)
{
        printf("-d(daemon)running background\n");
        printf("-p(--port):\n");
        printf("-h(help):heip information\n");
        printf("\n exampla:%s -d -p 8888 -h \n",progname);
        return;
}

/*信号*/
void signal_stop(int signum)
{
        if(SIGTERM == signum)
        {
        printf("received SIGTERM\n");
                g_stop=1;
        }
        return ;
}


